import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Iterator;
import java.util.Random;
import java.util.Scanner;
import java.io.*;


/**
 * A class representing a piece generator. When instanced, the piece generator will create two bags that each
 * hold one of each piece in random order. When a bag is empty the other bag will take over while the first
 * one is refilled.
 */
public class PieceGenerator implements Serializable
{
    /**
     * The Player object controlling the PieceGenerator.
     */
    private Player myPlayer;


    /**
     * Used to generate random numbers internally.
     */
    private Random rand;

    /**
     * Seed for the random generator
     */
    private int seed;

    /**
     * A list of "bags" that hold randomly generated pieces.
     */
    private LinkedList<ShuffleBag<Piece> > bags;

    /**
     * The number of bags held. Determines how far we can look ahead in peekNext()
     */
    static int NUMBER_OF_BAGS = 2;


    /**
     * Constructor for PieceGenerator
     *
     * @param player the player to whom this object belongs to
     * @param seed a seed for the random generator
     */
    public PieceGenerator(Player player, int seed)
    {
        myPlayer = player;
        rand = new Random(seed);
		this.seed = seed;
        bags = new LinkedList<ShuffleBag<Piece> >();
        for (int i = 0; i < NUMBER_OF_BAGS; i++) {
            addNewBag();
        }
    }

    /**
     * Get the next randomly generated piece
     *
     * @return     a random piece
     */
    public Piece getNext()
    {
		if(myPlayer.isSplitting()) {
			myPlayer.useSplit();
			return new Piece(myPlayer, 7, 0);
		} else {
			ShuffleBag<Piece> sb = bags.getFirst();
			if (sb.isEmpty()) {
				bags.removeFirst();
				addNewBag();
				sb = bags.getFirst();
			}
			return sb.getNext();
		}
    }

    /**
     * Adds a bag containing randomly generated pieces at the end of the list
     *
     */
    private void addNewBag() {
        ShuffleBag<Piece> sb = new ShuffleBag<Piece>(seed);
        //ArrayList<int[][]> v;
        //Iterator<ArrayList<int[][]> > i = pieceStates.iterator();
		//int pieceType = 0;

		//for (int pieceType=0; pieceType < Multitris.pieceStates.size(); pieceType++) {
		for (int pieceType=0; pieceType < 7; pieceType++) {
            ArrayList<int[][]> rotations = Multitris.pieceStates.get(pieceType);
            //sb.add(new Piece(myPlayer,v.get(rand.nextInt(v.size()))));
			sb.add(new Piece(myPlayer, pieceType, rand.nextInt(rotations.size())));
        }
        sb.shuffle();
        bags.addLast(sb);
    }

    /**
     * Looks at a future piece held in one of the ShuffleBags.
     *
     * @param offset The offset index of the piece. The next piece is at index 0
     * @return     The piece with the given offset in the list of upcoming pieces
     */
    public Piece peekNext(int offset)
    {
        Iterator<ShuffleBag<Piece> > it = bags.iterator();
        ShuffleBag<Piece> sb = bags.getFirst();
        while (it.hasNext() && offset >= 0) {
            sb = it.next();
            if (offset >= sb.size()) {
                offset -= sb.size();
            } else {
                break;
            }
        }
        return sb.get(offset);
    }

}
